
#ifndef _TTG_PIPELINE_ISUB_PIPELINE_
#define _TTG_PIPELINE_ISUB_PIPELINE_
#include "Common/Definitions.h"

#include <string>
#include "Common/Errors.h"
#include "IPipeline.h"

//Definition of used class.
namespace ttg
{
	namespace pipeline
	{
		class UserContext;
	}
}

namespace ttg_internal
{
	namespace pipeline
	{
		//Non-template version of SubPipeline.
		class ISubPipeline :public ttg::structures::NamedObject
		{
			private:
				std::string in_type;
				std::string out_type;
			protected:
				//Creates sub pipeline.
				//in_type == typeid(InType).name() of subpipeline.
				//out_type == typeid(OutType).name() of subpipeline.
				inline ISubPipeline(const char *name,
									const char *in_type, const char *out_type)
					:NamedObject(name)
				{
					this->in_type = in_type;
					this->out_type = out_type;
				}
				//Non-template version of the start.
				//Will be used for sending data to SubPipeline.
				//data == Enumerator<> *, d == ReleasableValue<> *.
				virtual void start(void *data, void *d) = 0;
			public:
				virtual void setUserContext(ttg::pipeline::UserContext *context) = 0;
				template <class InType, class OutType>
				inline void start(ttg::structures::Enumerator<InType> &data,
								  ttg::structures::Delegate<void, std::vector<OutType> *> *d)
				{
					//Checking.
					if (in_type != typeid(InType).name() ||
						out_type != typeid(OutType).name())
						throw ttg::Error(ttg::Error::FATAL, "ISubPipeline", "start",
										 "Type of data does not correspond to SubPipeline type");
					//Launching.
					start((void *)&data, (void *)d);
				}
		};
	}
}

#endif
